package com.yuyou.fn.portal.service.impl;

import com.github.wens.mybatisplus.examples.Example;
import com.github.wens.mybatisplus.toolkit.IdWorker;
import com.github.wens.mybatisplus.toolkit.StringUtil;
import com.yuyou.fn.common.exception.BusException;
import com.yuyou.fn.common.util.TimeUtils;
import com.yuyou.fn.educational.entity.ClassTime;
import com.yuyou.fn.educational.entity.CustomerBindStudent;
import com.yuyou.fn.educational.entity.Student;
import com.yuyou.fn.educational.entity.StudentReg;
import com.yuyou.fn.educational.service.IClassTimeService;
import com.yuyou.fn.educational.service.ICustomerBindStudentService;
import com.yuyou.fn.educational.service.IStudentRegService;
import com.yuyou.fn.educational.service.IStudentService;
import com.yuyou.fn.educational.vo.StudentRegQueryVo;
import com.yuyou.fn.portal.entity.OuterCourseClass;
import com.yuyou.fn.portal.service.IOuterCourseClassService;
import com.yuyou.fn.portal.vo.CourseClassResultVo;
import com.yuyou.fn.portal.vo.ShoppingCartDetailVo;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.formula.functions.T;
import org.springframework.stereotype.Service;

import com.yuyou.fn.portal.mapper.OuterShoppingcartMapper;
import com.yuyou.fn.portal.entity.OuterShoppingcart;
import com.yuyou.fn.portal.service.IOuterShoppingcartService;
import com.github.wens.framework.service.impl.SuperServiceImpl;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * OuterShoppingcart 表数据服务层接口实现类
 */
@Service
public class OuterShoppingcartServiceImpl extends SuperServiceImpl<OuterShoppingcartMapper, OuterShoppingcart, Long> implements IOuterShoppingcartService {
    @Resource
    private IStudentRegService studentRegService;

    @Resource
    private IOuterCourseClassService outerCourseClassService;

    @Resource
    private IStudentService studentService;

    @Resource
    private ICustomerBindStudentService customerBindStudentService;

    @Resource
    private IClassTimeService classTimeService;

    @Override
    public List<OuterShoppingcart> findOuterShoppingcartByCondition(Long userId, Long studentId) {
        Example<OuterShoppingcart> example = OuterShoppingcart.createExample();
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("userId", userId);
        String studentIds = "%" + studentId + "%";
        criteria.andLike("studentIds", studentIds);
        return findListByExample(example);
    }

    @Override
    public OuterShoppingcart findOuterShoppingcartByCondition(Long userId, Long studentId,Long classId) {
        Example<OuterShoppingcart> example = OuterShoppingcart.createExample();
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("userId", userId);
        criteria.andEqualTo("classId", classId);
        String studentIds = "%" + studentId + "%";
        criteria.andLike("studentIds", studentIds);
        return findOneByExample(example);
    }

    @Override
    @Transactional
    public void updateShoppingCartStudent(List<Long> studentIds , Long outerShoppingcartId, Long userId) {

        OuterShoppingcart changeOuterShoppingcart = this.findById(outerShoppingcartId);

        List<OuterCourseClass> shoppingCartCourseClasses = null;
        for(Long studentId : studentIds){
            List<Long> classIds = new ArrayList<Long>();
            if(StringUtils.isEmpty(changeOuterShoppingcart.getStudentIds()) || !changeOuterShoppingcart.getStudentIds().contains(studentId.toString())){
                if(shoppingCartCourseClasses == null ){
                    shoppingCartCourseClasses = outerCourseClassService.findByClassIds(Arrays.asList(changeOuterShoppingcart.getClassId()));
                }
                    /*添加学员，检查已有购物车，和该学员原有的课程的时间是否与添加的课程时间冲突* */
                List<OuterShoppingcart> outerShoppingcarts = this.findOuterShoppingcartByCondition(userId, studentId);
                for (OuterShoppingcart outerShoppingcart : outerShoppingcarts) {
                    classIds.add(outerShoppingcart.getClassId());
                }
                StudentRegQueryVo studentRegQueryVo = new StudentRegQueryVo();
                studentRegQueryVo.setStudentId(studentId);
                List<StudentReg> studentRegs = studentRegService.findStudentClassIds(studentId, Arrays.asList("0"));
                for (StudentReg studentReg : studentRegs) {
                    classIds.add(studentReg.getClassId());
                }
                List<OuterCourseClass> outerCourseClasses = outerCourseClassService.findByClassIds(classIds);
                String checkTime = checkClassTime(shoppingCartCourseClasses, outerCourseClasses);
                if (!"ok".equals(checkTime)) {
                    throw new BusException(checkTime);
                }
            }
        }

        OuterShoppingcart update  = new OuterShoppingcart() ;
        update.setOuterShoppingcartId(outerShoppingcartId);
        update.setStudentIds(StringUtils.join(studentIds,","));
        update.setUpdateTime(TimeUtils.now());
        updateSelectiveById(update);
    }

    /*查询是否已经存在该学生，所选的购物车是否时间上冲突*/
    @Transactional
    @Override
    public void addNewStudentToCart(List<Long> outerShoppingCartIds, Student student, Long userId) {
        HashMap<String, String> resultMap = new HashMap<String, String>();
        if ( student.getName()==null ||"".equals(student.getName()) || student.getPhoneNo()==null || "".equals(student.getPhoneNo())){
            throw  new  BusException("请完善学生信息");
        }
        Example<CustomerBindStudent> studentExample = CustomerBindStudent.createExample();
        Example.Criteria criteria = studentExample.createCriteria();
        criteria.andEqualTo("userId", userId);
        criteria.andEqualTo("studentName", student.getName());
        criteria.andEqualTo("phoneNo", student.getPhoneNo());
        if (customerBindStudentService.countByExample(studentExample)> 0) {
            throw  new  BusException("已经存在该学生");
        }
        Student student1=studentService.findByNameAndPhone(student);
        if (student1!=null){
            student=student1;
        }else{
            student.setStudentId(IdWorker.getId());
            student.setCreateTime(TimeUtils.now());
            student.setUpdateTime(TimeUtils.now());
            studentService.insertSelective(student);
        }

        CustomerBindStudent customerBindStudent = new CustomerBindStudent();
        customerBindStudent.setUserId(userId);
        customerBindStudent.setCreateTime(TimeUtils.now());
        customerBindStudent.setUpdateTime(TimeUtils.now());
        customerBindStudent.setPhoneNo(student.getPhoneNo());
        customerBindStudent.setStudentName(student.getName());
        customerBindStudent.setStudentId(student.getStudentId());
        customerBindStudent.setSchoolName(student.getSchool());
        customerBindStudent.setSex(student.getSex());
        customerBindStudentService.insertSelective(customerBindStudent);
        if (outerShoppingCartIds!=null && outerShoppingCartIds.size() > 0) {
            List<OuterShoppingcart> outerShoppingcartList = this.findByIds(outerShoppingCartIds);
            List<Long> classIds = new ArrayList<Long>();
            for (OuterShoppingcart outerShoppingcart : outerShoppingcartList) {
                classIds.add(outerShoppingcart.getClassId());
            }
            List<OuterCourseClass> outerCourseClasses = outerCourseClassService.findByClassIds(classIds);
            List<OuterCourseClass> outerCourseClasses1 = outerCourseClasses;
            String check = checkClassTime(outerCourseClasses, outerCourseClasses1);
            if (!"ok".equals(check)) {
                throw  new  BusException(check);
            } else {
                for (Long shoppingCartId : outerShoppingCartIds) {
                    OuterShoppingcart outerShoppingcart = this.findById(shoppingCartId);
                    String newStudentIds="";
                    if (outerShoppingcart.getStudentIds()!=null && !"".equals(outerShoppingcart.getStudentIds())){
                        newStudentIds = outerShoppingcart.getStudentIds() + "," + student.getStudentId();
                    }else{
                        newStudentIds =student.getStudentId()+"";
                    }

                    outerShoppingcart.setStudentIds(newStudentIds);
                    this.updateSelectiveById(outerShoppingcart);
                }
            }
        }


    }

    @Override
    public void addToShoppingCart(Long classId,Long userId) {
        Example<OuterShoppingcart> example=OuterShoppingcart.createExample();
        Example.Criteria criteria=example.createCriteria();
        criteria.andEqualTo("userId",userId);
        criteria.andEqualTo("classId",classId);
        if(this.countByExample(example)>0){
            throw new BusException("购物车已存在相同内容");
        }
        OuterShoppingcart outerShoppingcart=new OuterShoppingcart();
        outerShoppingcart.setClassId(classId);
        outerShoppingcart.setUserId(userId);
        outerShoppingcart.setCreateTime(TimeUtils.now());
        outerShoppingcart.setUpdateTime(TimeUtils.now());
        this.insertSelective(outerShoppingcart);
    }

    @Override
    public void deleteShoppingCart(List<Long> outerShoppingCartIds,Long userId) {
        Example<OuterShoppingcart> example=OuterShoppingcart.createExample();
        Example.Criteria criteria=example.createCriteria();
        criteria.andEqualTo("userId",userId);
        List<Long> list=new ArrayList<Long>();
        criteria.andIn("outerShoppingcartId",outerShoppingCartIds);
        this.deleteByExample(example);
    }


    public int  toMini(Date date){
        return (int)( date.getTime()/1000/60  - 24720000l/*2017-01-01*/ ) ;
    }
    private BitSet toBitSet(List<ClassTime> classTimeList, SimpleDateFormat dateSdf, SimpleDateFormat timeSdf)  {
        BitSet bitSet = new BitSet();
        try{
            for(ClassTime classTime : classTimeList ){
                String date = dateSdf.format(classTime.getClassDate());
                Date start = timeSdf.parse(date +" "+ classTime.getStartTime()) ;
                Date end = timeSdf.parse(date + " " + classTime.getEndTime()) ;
                bitSet.set(toMini(start),toMini(end) ,true );
            }
        }catch (ParseException e){
            throw  new BusException("对比课程时间段发生异常");
        }

        return bitSet;
    }

    @Override
    public  String checkClassTime(List<OuterCourseClass> list1, List<OuterCourseClass> list2)  {
        SimpleDateFormat dateSdf = new SimpleDateFormat("yyyy-MM-dd");
        SimpleDateFormat timeSdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");

        HashMap<String, String> checkMap = new HashMap<String, String>();

        for (OuterCourseClass shoppingCartCourse : list1) {
            List<ClassTime> classTimeList1 = classTimeService.findClassTimeByClassId(shoppingCartCourse.getClassId());
            for (OuterCourseClass outerCourseClass : list2) {
                if (outerCourseClass.getClassId().equals(shoppingCartCourse.getClassId())) {
                    continue;
                }
                if (checkMap.containsKey(shoppingCartCourse.getClassId() + "-" + outerCourseClass.getClassId())) {
                    continue;
                }
                checkMap.put(outerCourseClass.getClassId() + "-" + shoppingCartCourse.getClassId(), "1");
                List<ClassTime> classTimeList2 = classTimeService.findClassTimeByClassId(outerCourseClass.getClassId());
                BitSet bitSet = toBitSet(classTimeList1, dateSdf, timeSdf);
                BitSet bitSet2 = toBitSet(classTimeList2, dateSdf, timeSdf);

                String message=shoppingCartCourse.getClassName()+"与"+outerCourseClass.getClassName()+"的上课时间冲突";
                if (bitSet.intersects(bitSet2)) return  message;
            }
        }
        return "ok";
    }

    @Override
    public Long countNumByUserId(Long userId) {
        Example<OuterShoppingcart> example=OuterShoppingcart.createExample();
        example.createCriteria().andEqualTo("userId",userId);

        return this.countByExample(example);
    }

    @Override
    public List<ShoppingCartDetailVo> findShoppingCartList(Long userId) {
        Example<OuterShoppingcart> example=OuterShoppingcart.createExample();
        example.createCriteria().andEqualTo("userId",userId);
       // example.selectProperties("classId");
        List<OuterShoppingcart> list=this.findListByExample(example);
        List<ShoppingCartDetailVo> shoppingCartDetailVoList=new ArrayList<ShoppingCartDetailVo>();
        for (OuterShoppingcart outerShoppingcart:list){
            ShoppingCartDetailVo shoppingCartDetailVo=new ShoppingCartDetailVo();
            shoppingCartDetailVo.setOuterShoppingCartId(outerShoppingcart.getOuterShoppingcartId());
            shoppingCartDetailVo.setCourseClassResultVo(outerCourseClassService.findDetailByClassId(outerShoppingcart.getClassId()));
            shoppingCartDetailVo.setStudentIds(outerShoppingcart.getStudentIds());
            shoppingCartDetailVoList.add(shoppingCartDetailVo);
        }

        return shoppingCartDetailVoList;
    }
}
